﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Casamiel.API.Application.Services;
using Casamiel.API.Application.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.Domain.Entity;
using Casamiel.Application;
using Casamiel.Domain;
using System.Net.Http;
using Casamiel.API.Application.Models.Store;
using static Casamiel.API.Application.Models.Store.ProductBase;
using Casamiel.Common.Extensions;
using Casamiel.Common;
using Casamiel.API.Application.Interface;
using System.Security.Cryptography;
using System.Text;
using System.Data;

namespace Casamiel.API.Controllers
{
	
    /// <summary>
    /// Dev controller.
    /// </summary>
    [Produces("application/json")]
    [Route("api/Dev")]
    [ApiVersionNeutral]
   // [TypeFilterAttribute(typeof(TestAuthorizationFilter))]
    public class DevController : Controller
    {
        //private readonly IMemberCardRepository _memberCard;
		/// <summary>
		/// 
		/// </summary>
        private readonly IicApiService _iicApiService;
        private readonly IAgentService _commonService;
		private readonly IUserLogService _userLogService;
		private readonly IStoreApiService _storeApiService;
        private readonly IStoreService _storeService;
        private readonly IAllPayService _payservice;
        private readonly IPaymentService _paymentService;
        private readonly ICasaMielSession _session;
        private readonly IPayGateWayService payGateWayService;
      
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Casamiel.API.Controllers.DevController"/> class.
        /// </summary>
        /// <param name="commonService">Common service.</param>
        /// <param name="allPayService">All pay service.</param>
        /// <param name="iicApiService">Iic API service.</param>
        /// <param name="mielSession">Miel session.</param>
        /// <param name="logService">Log service.</param>
        /// <param name="storeApiService">Store API service.</param>
        /// <param name="storeService">Store service.</param>
        /// <param name="paymentService">Payment service.</param>
        /// <param name="session">Session.</param>
        /// <param name="payGateWay">Pay gate way.</param>
        public DevController(IAgentService commonService, IAllPayService allPayService, IicApiService iicApiService, ICasaMielSession mielSession,IUserLogService logService,
                             IStoreApiService storeApiService,IStoreService storeService,IPaymentService paymentService,ICasaMielSession session,IPayGateWayService payGateWay)
		{ 
            _commonService = commonService;
			
			_iicApiService = iicApiService;
			_userLogService = logService;
			_storeApiService = storeApiService;
            this._payservice = allPayService;
            _storeService = storeService;
            this._paymentService = paymentService;
            this._session = session;
            this.payGateWayService = payGateWay;
		}

        /// <summary>
        /// Creates the alipay.
        /// </summary>
        /// <returns>The alipay.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>
        /// {"outtradeno":"c2334","amount":"333"}
        /// </remarks>
        [HttpPost]
        [Route("[action]")]
        public IActionResult CreateAlipay([FromBody]JObject data){
         var result=   payGateWayService.CreateAlipayOrder(data["outtradeno"].ToString(), data["amount"].ToDouble(0));
            return Ok(result);
        }
        /// <summary>
        /// Creates the wx app pay.
        /// </summary>
        /// <returns>The wx app pay.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>{"outtradeno":"c2334","amount":"333"}</remarks>
        [HttpPost]
        [Route("[action]")]
        public IActionResult CreateWxAppPay([FromBody]JObject data)
        {
            var result = payGateWayService.CreateWechatpayOrder(data["outtradeno"].ToString(), data["amount"].ToDouble(0));
            return Ok(result);
        }
        /// <summary>
        /// Createwxpublics the pay.
        /// </summary>
        /// <returns>The pay.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>
        /// {"outtradeno":"c2334","amount":"333","openid:"","appId":""}
        /// </remarks>
        [HttpPost]
        [Route("[action]")]
        public IActionResult CreatewxpublicPay([FromBody]JObject data)
        {
            var result = payGateWayService.CreateMiniWechatpayOrder(data["outtradeno"].ToString(), data["amount"].ToDouble(0),data["openid"].ToString(),data["appId"].ToString());
            return Ok(result);
        }
		//public DevController(IMemberCardRepository memberCard, IicApiService iicApiService)
		//{
		//    _memberCard = memberCard;
		//    _iicApiService = iicApiService;
		//}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="dto"></param>
		/// <returns></returns>
		/// 
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> getPrice([FromBody] IcPriceDto dto)
		{
			var zmodle = await _iicApiService.icprice(dto);
			//var zmodle = await _commonService.ICService.icprice(dto);
			return Ok(zmodle);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> icqrcodecreate([FromBody] IcQrcodeCreateDto data)
		{
			var model = await _iicApiService.icqrcodecreate(data);
			return Ok(model);//
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="qrcode"></param>
		/// <returns></returns>
	    [HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> icqrcodequery([FromBody] string qrcode)
		{
			var model = await _iicApiService.icqrcodequery("","",qrcode);
			return Ok(model);
		}
		 
		/// <summary>
		/// Paies the complete.
		/// </summary>
		/// <returns>The complete.</returns>
		/// <param name="tradeno">Tradeno.</param>
		/// <param name="outtradeno">Outtradeno.</param>
		/// <param name="amount">Amount.</param>
		/// <param name="mchid">Mchid.</param>
		[HttpPost]
        [Route("[action]")]
        public  IActionResult PayComplete(string tradeno,string outtradeno,double amount,string mchid)
        {
            var payed = _payservice.PayComplete(tradeno, outtradeno, amount, mchid);
            return new JsonResult(payed);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> productstockquery([FromBody] IcPriceDto dto)
        {
            var zmodle = await _iicApiService.productstockquery(dto);
            return Ok(zmodle);
        }
        /// <summary>
        /// Adds the user LO.
        /// </summary>
        /// <returns>The user LO.</returns>
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> AddUserLOg()
		{
			var logdata = new UserLog { Url = "", OPInfo = $"会员充值，卡号[111],金额11", OPTime = DateTime.Now, UserName ="ipop"};
		    await	_userLogService.AddAsync<ICasaMielSession>(logdata);
			return Ok(logdata);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="pageindex"></param>
		/// <param name="pagesize"></param>
		/// <returns></returns>
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> GetUserLog(int pageindex,int pagesize)
		{
			var list =await _commonService.UserLogService.GetListByPage<ICasaMielSession>(pageindex, pagesize, "", "ID desc");
			return new JsonResult(list);
		}
		/// <summary>
        /// Gets the dist.
        /// </summary>
        /// <returns>The dist.</returns>
        /// <param name="flat">Flat.</param>
        /// <param name="flng">Flng.</param>
        /// <param name="tlat">Tlat.</param>
        /// <param name="tlng">Tlng.</param>
		[HttpPost]
		[Route("[action]")]
		public IActionResult GetDist(double flat,double flng,double tlat,double tlng)
		{
			Map a = new Map { lat = flat, lng = flng };
			Map to = new Map { lng = tlng, lat = tlat };
			var d= _commonService.MapService.GetGistance(a, to);
			return Ok(new { distance = d });
		}
        /// <summary>
        /// Gets all store.
        /// </summary>
        /// <returns>The all store.</returns>
        /// <param name="flat">Flat.</param>
        /// <param name="flng">Flng.</param>
        /// <param name="distance">Distance.</param>
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> GetAllStore (double flat, double flng,double distance)
		{
			 var en= DistanceHelper.FindNeighPosition(flng,flat, distance);

			var list1 = await _commonService.StoreService.GeRectRangeAsync<ICasaMielSession>(en.MinLat, en.MinLng, en.MaxLat, en.MaxLng);
			Map a = new Map { lat = flat, lng = flng };
			//Map to = new Map { lng = tlng, lat = tlat };
			//var d = _commonService.MapService.GetGistance(a, to);
			//return Ok(new { distance = d });
			//var list = await  _commonService.StoreService.GetAllStore<ICasaMielSession>();
			for (int i = 0; i < 10000; i++)
			{
				foreach (var item in list1)
				{
					item.Distance = DistanceHelper.GetDistance(flat, flng, item.Latitude, item.Longitude);// _commonService.MapService.GetGistance(a, new Map { lat=item.Latitude.ToDouble(0), lng=item.Longitude.ToDouble(0)});
				}
			}
			
		    var entity =  list1.OrderBy(p=> p.Distance).ToList();
			return new JsonResult(entity);
		}

		/// <summary>
        /// GetPaymentRecord
		/// </summary>
		/// <param name="pageindex"></param>
		/// <param name="pagesize"></param>
		/// <param name="state"></param>
		/// <returns></returns>
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> GetPaymentRecord(int pageindex, int pagesize,int state)
		{
			var list = await _commonService.PaymentService.GetListByPage<ICasaMielSession>(pageindex, pagesize, $"state={state}", "ID desc");
			return new JsonResult(list);
		}
		[HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> icchargelist(string card,string mobile)
		{
			var zmodel=	await _iicApiService.icchargelist(card, mobile);
			return Ok(zmodel);
		}
        

        /// <summary>
        /// Gets the product.
        /// </summary>
        /// <returns>The product.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>{"storeid":"1","productid":"1"}</remarks>
        [HttpPost]
		[Route("[action]")]
		public async Task<IActionResult> getProduct([FromBody] JObject data)
		{
			var a = await _storeApiService.GetGoodsById(data["storeid"].ToString(), data["productid"].ToString());
			return new JsonResult(a);
			//var _httpClient = new HttpClient();;
			//_httpClient.Timeout = new TimeSpan(0, 0, 30);
			//_httpClient.DefaultRequestHeaders.Connection.Add("keep-alive");
			//List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
			//paramList.Add(new KeyValuePair<String, String>("storeid", data["storeid"].ToString()));
			//paramList.Add(new KeyValuePair<String, String>("productid", data["productid"].ToString()));
			//HttpResponseMessage response = new HttpResponseMessage();
			//response = await _httpClient.PostAsync(new Uri($"http://store.casamiel.cn/Goods/GetGoodsById"), new FormUrlEncodedContent(paramList));
			//var result = await response.Content.ReadAsStringAsync();
			//var dynamicdata = JsonConvert.DeserializeObject<JObject>(result);
			//var entity = JsonConvert.DeserializeObject<ProductBase>(dynamicdata["Data"].ToString());
			//return new JsonResult(entity);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		//[HttpPost]
      //  [Route("[action]")]
      //  public IActionResult Add([FromBody] MemberCard data)
      //  {
		    //await	_commonService.MemberCardService.AddAsync<ICasaMielSession>(data);
        //    return Ok(data ); 
        //}
        /// <summary>
        /// Get the specified mobile.
        /// </summary>
        /// <returns>The get.</returns>
        /// <param name="mobile">Mobile.</param>
        [HttpGet]
        [Route("[action]")]
        public async Task<IActionResult> Get(string mobile)
        {
            var enituy = await _commonService.MemberCardService.GetCardListAsyncByMobile<ICasaMielSession>(mobile);
             
            return Ok(enituy);
        }

        [HttpGet]
        [Route("[action]")]
        public async Task<IActionResult> CardnoMobile(string cardno,string mobile)
        {
            var enituy = await _commonService.MemberCardService.FindAsyncByCardnoMobile<ICasaMielSession>(cardno,mobile);
            return Ok(enituy);
        }
        /// <summary>
        /// CardnoMobile
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> CardnoMobile([FromBody]MemberCard data)
        {
            var entity = await _commonService.MemberCardService.FindAsyncByCardnoMobile<ICasaMielSession>(data.CardNo, data.Mobile);
            entity.UnBindTime = DateTime.Now;
            entity.State = 0;
            var a =await _commonService.MemberCardService.UpdateAsync<ICasaMielSession>(entity);
            return Ok(entity);
        }

        /// <summary>
        /// 消费
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public  async Task<IActionResult> icconsume([FromBody]IcconsumeDto data)
        {
            var zmodel = await _iicApiService.icconsume(data);
            return Ok(zmodel);
        }

        /// <summary>
        /// 支付
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> icconsumepay([FromBody]IcConsumepayDto data)
        {
            var zmodel = await _iicApiService.icconsumepay(data);
            return Ok(zmodel);
        }
        /// <summary>
        /// Ics the consume back.
        /// </summary>
        /// <returns>The consume back.</returns>
        /// <param name="data">Data.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> IcConsumeBack([FromBody]IcConsumeBackDto data)
        {
            var zmodel = await _iicApiService.icconsumeback(data);
            return Ok(zmodel);
        }

        /// <summary>
        /// Cconsumelist the specified cardno, mobile, startdate and enddate.
        /// </summary>
        /// <returns>The cconsumelist.</returns>
        /// <param name="cardno">Cardno.</param>
        /// <param name="mobile">Mobile.</param>
        /// <param name="startdate">Startdate.</param>
        /// <param name="enddate">Enddate.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> cconsumelist(string cardno, string mobile, string startdate, string enddate){
            var zmodel = await _iicApiService.icconsumelist(cardno, mobile, startdate, enddate);
            return Ok(zmodel);
        }
        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> icorderstate([FromBody]IcorderstateDto data)
        {
            var zmodel = await _iicApiService.icorderstate(data);
            //var zmodel = await _commonService.ICService.icorderstate(data);
            return Ok(zmodel);
        }
        /// <summary>
        /// Members the unicregist.
        /// </summary>
        /// <returns>The unicregist.</returns>
        /// <param name="cardno">Cardno.</param>
        /// <param name="mobile">Mobile.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> MemberUnicregist(string cardno,string mobile)
        {
            var mcard = await _commonService.MemberCardService.FindAsyncByCardnoMobile<ICasaMielSession>(cardno,mobile);
            if (mcard == null)
            {
                return new JsonResult(new { code = -16, content = "", msg = "会员卡已经解绑" });
            }
             
            if (mcard.CardType == "2")
            {
                var result = await _iicApiService.GetCardBalance(cardno);
                if (result.code == 0)
                {
                    var vc = JsonConvert.DeserializeObject<JObject>(result.content);
                    if (Convert.ToDecimal(vc["directmoney"].ToString()) > 0)
                    {
                        return new JsonResult(new { code = -11, content = "", msg = "卡内有余额不能解绑！" });
                    }

                    //                "totalmoney": 598.01,
                    //"directmoney": 598.01,
                    //"othermoney": 0,
                }
            }
            var a = await _iicApiService.Unicregist(cardno,mobile);
            var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
            if (a.code == 0 || a.code == 103)//14手机号和会员卡号不匹配(已解）
            {
                mcard.IsBind = false;
                mcard.UnBindTime = DateTime.Now;
				await _commonService.MemberCardService.UpdateAsync<ICasaMielSession>(mcard);
                //await _memberCard.UnitOfWork.SaveChangesAsync();
               // _cacheService.Remove(Constant.MYCARDS_PREFIX + mobile);
                //var logdata = new UserLog { Url = Request.GetAbsoluteUri(), OPInfo = $"解绑会员卡,卡号:[{data.cardno}]", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                //_userLog.Add(logdata);
                return new JsonResult(new { code = 0, content = "", msg = "解绑成功！" });
            }
            var n = new { code = a.code, content = rnt, msg = a.msg };
            return new JsonResult(n);
        }
        /// <summary>
        /// Gets the URL.
        /// </summary>
        /// <returns>The URL.</returns>
        /// <param name="url">URL.</param>
        [HttpPost]
        [Route("[action]")]
        public IActionResult GetUrl(string url)
        {
            return Ok(GetShortUrl(url));
        }
        /// <summary>
        /// Gets the short URL.
        /// </summary>
        /// <returns>The short URL.</returns>
        /// <param name="url">URL.</param>
        public static string GetShortUrl(string url)
        {
            //可以自定义生成MD5加密字符传前的混合KEY
            string key = DateTime.Now.ToString();
            //要使用生成URL的字符
            string[] chars = new string[]{
             "a","b","c","d","e","f","g","h",
             "i","j","k","l","m","n","o","p",
             "q","r","s","t","u","v","w","x",
             "y","z","0","1","2","3","4","5",
             "6","7","8","9","A","B","C","D",
             "E","F","G","H","I","J","K","L",
             "M","N","O","P","Q","R","S","T",
             "U","V","W","X","Y","Z"
              };

            //对传入网址进行MD5加密
            byte[] bytes;
            using (var md5 = MD5.Create())
            {
                bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(key + url));
            }
            var result = new StringBuilder();
            foreach (byte t in bytes)
            {
                result.Append(t.ToString("X2"));
            }
            string hex = result.ToString();// System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(key + url, "md5");

            string[] resUrl = new string[4];
            for (int i = 0; i < 4; i++)
            {
                //把加密字符按照8位一组16进制与0x3FFFFFFF进行位与运算
                int hexint = 0x3FFFFFFF & Convert.ToInt32("0x" + hex.Substring(i * 8, 8), 16);
                string outChars = string.Empty;
                for (int j = 0; j < 6; j++)
                {
                    //把得到的值与0x0000003D进行位与运算，取得字符数组chars索引
                    int index = 0x0000003D & hexint;
                    //把取得的字符相加
                    outChars += chars[index];
                    //每次循环按位右移5位
                    hexint = hexint >> 5;
                }
                //把字符串存入对应索引的输出数组
                resUrl[i] = outChars;
            }
            return resUrl[new Random().Next(0, 3)];
        }

    }
}